package menu

import (
	"context"
	"jinrigaoping/pkg/constant"
	"jinrigaoping/pkg/mctx"
	"jinrigaoping/rpc/sys/sys"
	"sort"

	"jinrigaoping/api/superadmin/internal/svc"
	"jinrigaoping/api/superadmin/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type MenuNavLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewMenuNavLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MenuNavLogic {
	return &MenuNavLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *MenuNavLogic) MenuNav(req *types.MenuNavReq) (resp *types.MenuNavRes, err error) {

	userId, userType, err := mctx.CheckAdminOrUser(l.ctx)
	if err != nil {
		return nil, err
	}

	// 需要获取所有菜单

	var menuList []*sys.SysMenuInfoRes
	if userType == constant.SuperAdminUser {

		menuResp, err := l.svcCtx.SysRpc.SysMenuList(l.ctx, &sys.SysMenuListReq{})
		if err != nil {
			return nil, err
		}

		for _, v := range menuResp.List {
			menuList = append(menuList, &sys.SysMenuInfoRes{
				MenuId:      v.MenuId,
				ParentId:    v.ParentId,
				Name:        v.Name,
				Component:   v.Component,
				IsLink:      v.IsLink,
				MenuSort:    v.MenuSort,
				Path:        v.Path,
				Redirect:    v.Redirect,
				Title:       v.Title,
				Icon:        v.Icon,
				IsHide:      v.IsHide,
				IsKeepAlive: v.IsKeepAlive,
				IsAffix:     v.IsAffix,
				LinkUrl:     v.LinkUrl,
				MenuType:    v.MenuType,
				IsIframe:    v.IsIframe,
			})
		}

	} else if userType == constant.AdminUser {

		userInfo, err := l.svcCtx.SysRpc.SysUserInfo(l.ctx, &sys.SysUserInfoReq{
			Id: userId,
		})

		if err != nil {
			return nil, err
		}

		menuResp, err := l.svcCtx.SysRpc.SysRoleMenuList(l.ctx, &sys.SysRoleMenuListReq{RoleId: userInfo.RoleId})
		if err != nil {
			return nil, err
		}

		for _, v := range menuResp.List {
			menuList = append(menuList, &sys.SysMenuInfoRes{
				MenuId:      v.MenuId,
				ParentId:    v.ParentId,
				Name:        v.Name,
				Component:   v.Component,
				IsLink:      v.IsLink,
				MenuSort:    v.MenuSort,
				Path:        v.Path,
				Redirect:    v.Redirect,
				Title:       v.Title,
				Icon:        v.Icon,
				IsHide:      v.IsHide,
				IsKeepAlive: v.IsKeepAlive,
				IsAffix:     v.IsAffix,
				LinkUrl:     v.LinkUrl,
				MenuType:    v.MenuType,
				IsIframe:    v.IsIframe,
			})
		}

	} else {
		return &types.MenuNavRes{
			List: make([]*types.SysMenuListItem, 0),
		}, nil
	}

	treeMenu := getTreeRecursive(menuList, 0)

	return &types.MenuNavRes{List: treeMenu}, nil
}

func getTreeRecursive(list []*sys.SysMenuInfoRes, parentId int64) []*types.SysMenuListItem {
	res := make([]*types.SysMenuListItem, 0)
	for _, v := range list {
		if v.ParentId == parentId {
			itemMenu := &types.SysMenuListItem{
				MenuId:    v.MenuId,
				Name:      v.Name,
				Path:      v.Path,
				Component: v.Component,
				Sort:      v.MenuSort,
				Redirect:  v.Redirect,
				Meta: types.SysMenuMeta{
					Title:       v.Name,
					IsLink:      "",
					IsHide:      false,
					IsKeepAlive: true,
					IsAffix:     false,
					IsIframe:    false,
					Roles:       []string{},
					Icon:        "",
				},
			}
			itemMenu.Children = getTreeRecursive(list, v.MenuId)
			if len(itemMenu.Children) > 0 {
				sort.SliceStable(itemMenu.Children, func(i, j int) bool {
					return itemMenu.Children[i].Sort < itemMenu.Children[j].Sort
				})
			}
			res = append(res, itemMenu)
		}
	}
	return res
}
